package jfuzzyprincepless.zarchive.algorithm.structure.ifcnstr;

import java.util.*;

import jfuzzyprincepless.agents.INegotiatingAgent;
import jfuzzyprincepless.zarchive.algorithm.structure.BaseNegotiationConstruction;
import jfuzzyprincepless.zarchive.algorithm.structure.ChainCommand;
import jfuzzyprincepless.zarchive.algorithm.structure.ICommandConstruction;
import jfuzzyprincepless.zarchive.negotiation.ZArchNegotiationUtils;

/**
 * DESIGN NOTE:
 * fields {@link #thenCommands} and {@link #elseCommands}
 * contain commands to be ran in THEN and ELSE - branches
 * but this class do not distinguish {@link #thenCommands}
 * and {@link #elseCommands}
 *
 * and it is concept of agents' negotiation IF-construction
 * implementation
 *
 * agents from {@link #condition} decide what command to call
 * and how to setup executor of the command
 *
 * @see jfprincesstests.systemtests.TestInvestmentCompNegotiation#testInvestmentNegotiation()
 */
public class NegotiationIfConstruction
	extends BaseNegotiationConstruction
	implements INegotiationIfConstruction
{
	private INegotiationCondition condition;
	private ChainCommand thenCommands;
	private ChainCommand elseCommands;

	public NegotiationIfConstruction(
		INegotiationCondition condition,
		List<ICommandConstruction> thenCommands,
		List<ICommandConstruction> elseCommands,
		List<INegotiatingAgent> agentsList
	) {
		super(agentsList);
		this.condition = condition;
		this.thenCommands = new ChainCommand(thenCommands);
		this.elseCommands = new ChainCommand(elseCommands);
	}

	public NegotiationIfConstruction(
		INegotiationCondition condition,
		List<ICommandConstruction> thenCommands,
		List<ICommandConstruction> elseCommands
	) {
		this(
			condition,
			thenCommands,
			elseCommands,
			new ArrayList<INegotiatingAgent>()
		);
	}

	public NegotiationIfConstruction() {
		this(
			INegotiationCondition.EMPTY_CONDITION,
			ICommandConstruction.EMPTY_LIST,
			ICommandConstruction.EMPTY_LIST
		);
	}

	/**
	 * DESIGN NOTE:
	 * is never used, but is here because
	 * {@link jfuzzyprincepless.zarchive.algorithm.structure.ifcnstr.IIfConstruction}
	 * sould look like real if
	 */
	@Override
	public INegotiationCondition getCondition() {
		return condition;
	}

	@Override
	public List<ICommandConstruction> getThenCommands() {
		return thenCommands.getCommandsList();
	}

	@Override
	public List<ICommandConstruction> getElseCommands() {
		return elseCommands.getCommandsList();
	}

	@Override
	public void extractAgentsFromConstructions() {
		agents.clear();

		// DECIDE: implement it in strategy: which agents to add in export
		ZArchNegotiationUtils.addAgents(
			thenCommands.getCommandsList(),
			agents,
			ZArchNegotiationUtils.CMD_IS_AGENT
		);
		ZArchNegotiationUtils.addAgents(
			elseCommands.getCommandsList(),
			agents,
			ZArchNegotiationUtils.CMD_IS_AGENT
		);
		agents.addAll(condition.getAgents());
	}

	@Override
	public List<ICommandConstruction> getCommandsList() {
		List<ICommandConstruction> result =
			new ArrayList<ICommandConstruction>();
		result.addAll(getThenCommands());
		result.addAll(getElseCommands());
		return result;
	}
}
